package com.zx.mes.upms.hyl.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zx.mes.hyl.controller.BaseMethod;
import com.zx.mes.hyl.pagemodel.PageParam;
import com.zx.mes.hyl.response.ObjectRestResponse;
import com.zx.mes.hyl.response.TableResultResponse;
import com.zx.mes.upms.hyl.entity.Permission;
import com.zx.mes.upms.hyl.entity.Role;
import com.zx.mes.upms.hyl.entity.RolePermission;
import com.zx.mes.upms.hyl.entity.RoleUser;
import com.zx.mes.upms.hyl.pagemodel.RolePage;
import com.zx.mes.upms.hyl.pagemodel.TreeNode;
import com.zx.mes.upms.hyl.service.PermissionService;
import com.zx.mes.upms.hyl.service.RolePermissionService;
import com.zx.mes.upms.hyl.service.RoleService;
import com.zx.mes.upms.hyl.service.RoleUserService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 角色表 前端控制器
 * </p>
 *
 * @author 华云龙
 * @since 2019-02-15
 */
@Log4j2
@RestController
@RequestMapping("/role")
public class RoleController extends BaseMethod<RoleService, Role> {

    @Autowired
    private RoleUserService sysRoleUserService;

    @Autowired
    private RolePermissionService sysRolePermissionService;

    @Autowired
    private PermissionService sysPermissionService;


    /**
     * 使用要求:所有的表都必需有唯一key值,且名称为 REFLECTION_FIELD_NAME (id)
     *
     * @param entity 实体类(pojo)
     * @return ObjectRestResponse
     */
    @PreAuthorize("hasAuthority('back:role:save')")
    @ApiOperation(value = "添加一笔数据", notes = "根据id自生成(数据库),还是前端生成(自身成36位)")
    @PostMapping(value = "/add")
    public ObjectRestResponse<Role> save(@RequestBody Role entity) {
        entity.setId(baseControllerExt.getUUID())
                .setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now());
        return super.add(entity);
    }

    @PreAuthorize("hasAuthority('back:role:query')")
    @ApiOperation(value = "根据所传id(数据库表的主键必需是id才能用)")
    @GetMapping(value = "getOne/{id}")
    public ObjectRestResponse<Role> getById(@ApiParam("id 是数据库的唯一主键") @PathVariable String id) {
        return super.get(id);
    }

    /**
     * {
     * "status": 200,
     * "message": "数据更新成功!",
     * "data": null,
     * "rel": true
     * }
     *
     * @param entity 对应实体类
     * @return ObjectRestResponse
     */
    @PreAuthorize("hasAuthority('back:role:update')")
    @ApiOperation(value = "单笔更新操作", notes = "必需根据id来更新")
    @PutMapping(value = "update")
    public ObjectRestResponse<Role> updateByEntity(@RequestBody Role entity) {
        entity.setUpdateTime(LocalDateTime.now());
        return super.update(entity);
    }

    @PreAuthorize("hasAuthority('back:role:delete')")
    @ApiOperation(value = "单笔删除操作", notes = "必需根据id来删除")
    @DeleteMapping(value = "delete/{id}")
    public ObjectRestResponse<Role> del(@PathVariable String id) {
        /// 中间表先删除
        this.sysRolePermissionService.remove(new QueryWrapper<RolePermission>()
                .lambda().eq(RolePermission::getRoleId, id));
        /// 再删除角色表中的角色
        return super.remove(id);
    }

    @PreAuthorize("hasAuthority('back:role:query')")
    @ApiOperation(value = "获取所有的数据", notes = "一般不推荐使用,小数据量可以")
    @GetMapping(value = "/all")
    public List<Role> getAll() {
        return super.all();
    }


    @PreAuthorize("hasAuthority('back:role:query')")
    @ApiOperation(value = "分页操作", notes = "params HashMap example = \"page=1&limit=5\"")
    @SuppressWarnings({"unchecked"})
    @GetMapping(value = "/page")
    public TableResultResponse page(@RequestParam Map<String, Object> params, Role entity) {
        TableResultResponse.Builder<Role> builder = new TableResultResponse.Builder();
        PageParam extPageParams = this.baseControllerExt.getPageParams(params);
        LambdaQueryWrapper<Role> lambda = new QueryWrapper<Role>().lambda();
        if (entity != null && StringUtils.isNotBlank(entity.getCode())) {
            lambda.like(Role::getCode, entity.getCode());
        }

        if (entity != null && StringUtils.isNotBlank(entity.getName())) {
            lambda.like(Role::getName, entity.getName());
        }

        List<Role> list = this.biz.page(new Page((long) extPageParams.getPage(), (long) extPageParams.getLimit()), lambda).getRecords();
        if (null != list && list.size() != 0) {
            builder.message("分页查询结果").total((long) list.size()).total((long) this.biz.count(null)).page((long) extPageParams.getPage()).rows(list);
        } else {
            builder.message("无数据").page(0L).rows(null);
        }

        return builder.build();
    }


    @PreAuthorize("hasAuthority('back:role:delete')")
    @DeleteMapping("/deleteBatch")
    public ObjectRestResponse<Role> deleteBatch(String ids) {
        ObjectRestResponse.Builder<Role> response = new ObjectRestResponse.Builder<>();
        /// 删除角色时,要处理 1.角色-用户中间表, 2.角色-权限表

        /// 参数检查
        if (StringUtils.isNotBlank(ids)) {
            List<String> list = this.baseControllerExt.divideStrToList(ids);
            if (list != null && list.size() > 0) {
                /// 1.删除 角色-用户中间表中的数据
                this.sysRoleUserService.remove(new QueryWrapper<RoleUser>().lambda().in(RoleUser::getRoleId, list));
                /// 2.删除 角色-权限中间表中的数据
                this.sysRolePermissionService.remove(new QueryWrapper<RolePermission>().lambda().in(RolePermission::getRoleId, list));
                /// 3.删除 角色表中的数据
                this.biz.removeByIds(list);
                response.message("批量删除成功!");
            } else {
                response.message("没有可删除的数据!");
            }
        } else {
            response.message("所传参数无效,请检查!");
        }
        return response.build();
    }

    /**
     * 给角色授权
     *
     * @param sysRole 角色
     * @return response
     */
    @PostMapping("/grantPermission")
    public ObjectRestResponse<Role> grantPermission(@RequestBody Role sysRole) {
        ObjectRestResponse.Builder<Role> response = new ObjectRestResponse.Builder<>();
        /// 先删除中间表的内容 1.角色-权限中间表

        /// 1.删除 角色-权限中间表
        /// 参数检查
        if (StringUtils.isNotBlank(sysRole.getRoleId()) && StringUtils.isNotBlank(sysRole.getPermissionIds())) {
            this.sysRolePermissionService.remove(new QueryWrapper<RolePermission>().lambda().eq(RolePermission::getRoleId, sysRole.getRoleId()));
            /// 2.组合后向 角色-权限中间表插入
            List<String> list = this.baseControllerExt.divideStrToList(sysRole.getPermissionIds());
            List<RolePermission> sysRolePermissionList = new ArrayList<>(128);
            list.forEach(item -> {
                RolePermission sysRolePermission = new RolePermission();
                sysRolePermission.setPermissionId(item).setRoleId(sysRole.getRoleId());
                sysRolePermissionList.add(sysRolePermission);
            });
            this.sysRolePermissionService.saveBatch(new ArrayList<>(sysRolePermissionList));
            response.message("权限授权成功!");
        } else {
            response.message("传参无效,请检查所传参数!");
        }
        return response.build();
    }

    /**
     * 根据角色id获取对应的权限id
     *
     * @param roleId 角色 id
     * @return RolePage
     */
    @GetMapping("/getPermissionByRoleId")
    public ObjectRestResponse<RolePage> getPermissionByRoleId(String roleId) {
        ObjectRestResponse.Builder<RolePage> response = new ObjectRestResponse.Builder<>();
        /// 1.从 角色-权限表中获取权限信息
        List<RolePermission> list = this.sysRolePermissionService.list(new QueryWrapper<RolePermission>().lambda().eq(RolePermission::getRoleId, roleId));
        if (list != null && list.size() > 0) {
            /// 2.从 权限表中获取权限详细信息
            List<String> permissionIdList = new ArrayList<>(32);
            list.forEach(item -> permissionIdList.add(item.getPermissionId()));
            List<Permission> sysPermissionList = this.sysPermissionService.list(new QueryWrapper<Permission>().lambda().in(Permission::getId, permissionIdList));
            response.message("角色获取权限详细信息成功!").data(sysPermissionList);
        } else {
            response.message("角色未获取到权限的详细信息!");
        }
        return response.build();
    }

    /**
     * 先获取第一层,依前端所选择,再展示下面相关内容,层层获取,可获得较高的性能
     *
     * @return response
     */
    @GetMapping("/getLazyPermission")
    public TableResultResponse<Permission> getLazyPermission() {
        TableResultResponse.Builder<Permission> response = new TableResultResponse.Builder<>();
        /// 获取第一层的menu
        List<Permission> permissionList = this.sysPermissionService.list(new QueryWrapper<Permission>()
                .lambda()
                .eq(Permission::getLevel, 1).eq(Permission::getType, 1));
        response.message("数据获取成功!").rows(permissionList).total(permissionList.size());
        return response.build();
    }

    /**
     * 获取第一层之后,下面的直接根据id寻找子数据
     *
     * @param id permission id
     * @return response
     */
    @GetMapping("/getLazyPermissionById")
    public TableResultResponse<Permission> getLazyPermissionById(String id) {
        TableResultResponse.Builder<Permission> response = new TableResultResponse.Builder<>();
        List<Permission> permissions = this.sysPermissionService.list(new QueryWrapper<Permission>().lambda().eq(Permission::getPid, id));
        response.message("数据获取成功!").rows(permissions).total(permissions.size());
        return response.build();
    }

    @GetMapping("/getPermissionTree")
    public TableResultResponse<TreeNode> getPermissionTree(){
        TableResultResponse.Builder<TreeNode> response = new TableResultResponse.Builder<>();
        List<Permission> permissions = this.sysPermissionService.list(new QueryWrapper<Permission>().lambda().eq(Permission::getLevel, 1));
        List<Permission> list = this.sysPermissionService.list();
        List<TreeNode> nodes = new ArrayList<>();
        permissions.stream().forEach(permission -> {
            TreeNode treeNode = new TreeNode();
            treeNode.setId(permission.getId()).setLabel(permission.getName());
            nodes.add(getTreeNode(treeNode, list));
        });
        response.rows(nodes).total(nodes.size()).message("权限树获取成功!");
        return response.build();
    }

    public TreeNode getTreeNode(TreeNode treeNode,List<Permission> list){
        for (int i = 0; i <list.size() ; i++) {
            Permission permission = list.get(i);
            if (StringUtils.isNotEmpty(permission.getPid()) && permission.getPid().equals(treeNode.getId())) {
                TreeNode node = new TreeNode();
                node.setId(permission.getId()).setPid(permission.getPid()).setLabel(permission.getName());
                treeNode.getChildren().add(node);
                getTreeNode(node, list);
            }
        }
        return treeNode;
    }


    public void getTreeNode2(Permission permission,List<Permission> list,List<TreeNode> nodeList){
        TreeNode treeNode = new TreeNode();
        treeNode.setId(permission.getId()).setLabel(permission.getName());
        boolean b = false;
        for (int i = 0; i < list.size() ; i++) {
            Permission p = list.get(i);
            if (StringUtils.isNotEmpty(p.getPid()) && p.getPid().equals(permission.getId())) {
                TreeNode node = new TreeNode();
///                node.setId(p.getId()).setLabel(p.getName()).setPid(p.getPid());
                getTreeNode2(p,list,node.getChildren());
                treeNode.getChildren().add(node);
            }
        }
        /// 每次添加一次导致有重复  这个要注意,以免下次又掉坑里了
        nodeList.add(treeNode);


    }
}

